﻿using System;
using System.Collections.Generic;

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

using Newtonsoft.Json;

using YTS.WEBAPI;
using YTS.Log;

using IOFileServer;
using IOFileServer.DataSupport;
using IOFileServer.StoreLibrary;

namespace YTS.IOFile.API.Controllers
{
    /// <summary>
    /// 键值对数据库存储接口
    /// </summary>
    public class KeyValuePairsDbController : BaseApiController
    {
        /// <summary>
        /// 配置键名称_目录哈希队列
        /// </summary>
        public const string CONFIG_KEY_NAME_STORE_CONFIGURATION = "StoreConfiguration";

        private readonly ILog log;
        private readonly IDictionary<string, StoreLibraryConfiguration> storeConfigs;
        private readonly IKeyValuePairsDb db;

        /// <summary>
        /// 初始化 - 键值对数据库存储接口
        /// </summary>
        public KeyValuePairsDbController(ILogger<KeyValuePairsDbController> _logger, IConfiguration configuration)
        {
            log = new APILogicGeneralLog<KeyValuePairsDbController>(_logger);
            IConfigurationSection storeConfigs_Section = configuration.GetSection(CONFIG_KEY_NAME_STORE_CONFIGURATION);
            storeConfigs = storeConfigs_Section.Get<IDictionary<string, StoreLibraryConfiguration>>();
            IPathRuleParsingRootConfig pathRuleParsing = new PathRuleParsingJSON(log);
            IDataFileIO fileIO = new DataFileIOJSON();
            db = new KeyValuePairsDb(storeConfigs, log, pathRuleParsing, fileIO);
        }

        /// <summary>
        /// 获取可操作数据区域根名单
        /// </summary>
        [HttpGet]
        public IEnumerable<BasicStoreLibrary> GetOperableStores() => db.GetOperableStores();

        /// <summary>
        /// 写入参数
        /// </summary>
        public class MWriteArgs
        {
            /// <summary>
            /// 数据区域标识
            /// </summary>
            public string root;
            /// <summary>
            /// 存储键值对
            /// </summary>
            public IDictionary<string, object> kvPairs;
        }
        /// <summary>
        /// 写入键值对数据
        /// </summary>
        /// <param name="arg">写入参数模型</param>
        /// <returns>执行结果, 受影响的条数</returns>
        [HttpPost]
        public Result<int> Write(MWriteArgs arg)
        {
            if (arg == null)
                return ResultStatueCode.ParameterError.To("参数为空!", 0);

            var logArgs = log.CreateArgDictionary();
            try
            {
                logArgs["arg.root"] = arg.root;
                logArgs["arg.kvPairs  (json)"] = JsonConvert.SerializeObject(arg.kvPairs);
                int successCount = db.Write(arg.root, arg.kvPairs);
                if (successCount <= 0)
                {
                    string name = @"无执行成功记录!";
                    log.Info(name, logArgs);
                }
                return ResultStatueCode.OK.To("写入完成", successCount);
            }
            catch (Exception ex)
            {
                string name = $"写入异常: {ex.Message}";
                log.Error(name, ex, logArgs);
                return ResultStatueCode.UnexpectedException.To(name, 0);
            }
        }

        /// <summary>
        /// 读取参数
        /// </summary>
        public class MReadArgs
        {
            /// <summary>
            /// 数据区域标识
            /// </summary>
            public string root;
            /// <summary>
            /// 键读取表达式集合
            /// </summary>
            public string[] keyExpressions;
        }
        /// <summary>
        /// 读取键值对数据
        /// </summary>
        /// <param name="arg">写入参数模型</param>
        /// <returns>匹配键读取表达式的键值对数据</returns>
        [HttpPost]
        public Result<IDictionary<string, object>> Read(MReadArgs arg)
        {
            var logArgs = log.CreateArgDictionary();
            IDictionary<string, object> result = null;
            try
            {
                logArgs["arg.root"] = arg.root;
                logArgs["arg.keyExpressions (json)"] = JsonConvert.SerializeObject(arg.keyExpressions);

                result = db.Read(arg.root, arg.keyExpressions);
                if (result == null || result.Count <= 0)
                {
                    string name = @"结果为空!";
                    log.Info(name, logArgs);
                }
                return ResultStatueCode.OK.To("读取完成", result);
            }
            catch (Exception ex)
            {
                string name = $"读取异常: {ex.Message}";
                log.Error(name, ex, logArgs);
                return ResultStatueCode.UnexpectedException.To(name, result);
            }
        }

    }
}
